Black and Scholes option model
library(tidyverse)
library(plotly)
option_prm <- function(S, X, t, r, sigma, put = FALSE) {
f <- 1 - put * 2
u <- 1/(sigma*t^0.5)
v <- log(S/X)
x <- (r + sigma^2 / 2) * t
d1 <- u * (v + x)
d2 <- d1 - (1/u)
C <- f * pnorm(f * d1) * S - f * pnorm(f * d2) * X * exp(-1 * r * t)
return(C)
}
S <- 20
X <- 22
t <- 90/365
r <- 0.05
sigma <- 0.1
call_spot <- data.frame(spot = seq(S-10, S+10, by=0.1)) %>% mutate(call_value = option_prm(S = spot, X = X, t = t, r = r, sigma = sigma, put = FALSE), lbound = (spot > X) * (spot - X))
n <- ggplot(call_spot) +
geom_line(aes(x = spot, y = call_value), color = "skyblue") +
geom_line(aes(x = spot, y = lbound), color = "tomato")
ggplotly(n, width = 800)
option_prm(S = S, X = X, t = t, r = r, sigma = sigma, put = TRUE)
[1] 1.750733
Option pay-off
pay_off_vals <- function(premium, S, X, put = FALSE) {
lbound <- max(0, S - 10)
ubound <- S + 10
x <- seq(lbound, ubound)
y <- (!put) * (x > X) * (x - X) + put * (x < X) * (X - x) - premium
return(data.frame(x, y))
}
S <- 42
X <- 42
t <- 365/365
r <- 0.05
sigma <- 0.1
call_prm <- option_prm(S = S, X = X, t = t, r = r, sigma = sigma)
put_prm <- option_prm(S = S, X = X, t = t, r = r, sigma = sigma, put = TRUE)
call_pay <- pay_off_vals(premium = call_prm, S = S, X = X)
put_pay <- pay_off_vals(premium = put_prm, S = S, X = X, put = TRUE)
put_call <- data.frame(spot = call_pay$x, call = call_pay$y, put = put_pay$y) %>% mutate(call_minus_put = call - put)
p <- ggplot(put_call) +
geom_line(aes(x = spot, y = call), color = "steelblue") +
geom_line(aes(x = spot, y = -put), color = "tomato") +
geom_line(aes(x = spot, y = call_minus_put), color = "turquoise") +
xlab("spot") + ylab("pay off")
ggplotly(p, width = 800)
X - X * exp(-1 * r * t)
[1] 2.048364
Put-call parity
S <- 42
X <- 45
t <- 365/365
r <- 0.05
sigma <- 0.1
C <- option_prm(S=S, X=X, t=t, r=r, sigma=sigma)
P <- option_prm(S=S, X=X, t=t, r=r, sigma=sigma, put=TRUE)
X_PV <- X*exp(-r*t)
cat("C =", C, ", P =", P, ", X_PV =", X_PV, "=> C + X_PV - P =", C + X_PV - P, "= S")
C = 1.318635 , P = 2.123959 , X_PV = 42.80532 => C + X_PV - P = 42 = S
LS0tCnRpdGxlOiAiT3B0aW9ucyIKb3V0cHV0OiAKICBodG1sX25vdGVib29rOiAKICAgIHRoZW1lOiB1bml0ZWQKLS0tCgojIEJsYWNrIGFuZCBTY2hvbGVzIG9wdGlvbiBtb2RlbAoKCmBgYHtyfQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShwbG90bHkpCgpvcHRpb25fcHJtIDwtIGZ1bmN0aW9uKFMsIFgsIHQsIHIsIHNpZ21hLCBwdXQgPSBGQUxTRSkgewoKZiA8LSAxIC0gcHV0ICogMgp1IDwtIDEvKHNpZ21hKnReMC41KQoKdiA8LSBsb2coUy9YKQoKeCA8LSAociArIHNpZ21hXjIgLyAyKSAqIHQKCmQxIDwtIHUgKiAodiArIHgpCgpkMiA8LSBkMSAtICgxL3UpCgpDIDwtIGYgKiBwbm9ybShmICogZDEpICogUyAtIGYgKiBwbm9ybShmICogZDIpICogIFggKiBleHAoLTEgKiByICogdCkKCnJldHVybihDKQoKfQoKUyA8LSAyMApYIDwtIDIyCnQgPC0gOTAvMzY1CnIgPC0gMC4wNQpzaWdtYSA8LSAwLjEKCmNhbGxfc3BvdCA8LSBkYXRhLmZyYW1lKHNwb3QgPSBzZXEoUy0xMCwgUysxMCwgYnk9MC4xKSkgJT4lIG11dGF0ZShjYWxsX3ZhbHVlID0gb3B0aW9uX3BybShTID0gc3BvdCwgWCA9IFgsIHQgPSB0LCByID0gciwgc2lnbWEgPSBzaWdtYSwgcHV0ID0gRkFMU0UpLCBsYm91bmQgPSAoc3BvdCA+IFgpICogKHNwb3QgLSBYKSkKCm4gPC0gZ2dwbG90KGNhbGxfc3BvdCkgKwogIGdlb21fbGluZShhZXMoeCA9IHNwb3QsIHkgPSBjYWxsX3ZhbHVlKSwgY29sb3IgPSAic2t5Ymx1ZSIpICsKICBnZW9tX2xpbmUoYWVzKHggPSBzcG90LCB5ID0gbGJvdW5kKSwgY29sb3IgPSAidG9tYXRvIikKZ2dwbG90bHkobiwgd2lkdGggPSA4MDApCgpvcHRpb25fcHJtKFMgPSBTLCBYID0gWCwgdCA9IHQsIHIgPSByLCBzaWdtYSA9IHNpZ21hLCBwdXQgPSBUUlVFKQpgYGAKCiMgT3B0aW9uIHBheS1vZmYKCmBgYHtyfQoKcGF5X29mZl92YWxzIDwtIGZ1bmN0aW9uKHByZW1pdW0sIFMsIFgsIHB1dCA9IEZBTFNFKSB7CiAgCiAgbGJvdW5kIDwtIG1heCgwLCBTIC0gMTApCiAgdWJvdW5kIDwtIFMgKyAxMAogIHggPC0gc2VxKGxib3VuZCwgdWJvdW5kKQogIHkgPC0gKCFwdXQpICogKHggPiBYKSAqICh4IC0gWCkgKyBwdXQgKiAoeCA8IFgpICogKFggLSB4KSAtIHByZW1pdW0KICAKICByZXR1cm4oZGF0YS5mcmFtZSh4LCB5KSkKICAKfQpTIDwtIDQyClggPC0gNDIKdCA8LSAzNjUvMzY1CnIgPC0gMC4wNQpzaWdtYSA8LSAwLjEKCmNhbGxfcHJtIDwtIG9wdGlvbl9wcm0oUyA9IFMsIFggPSBYLCB0ID0gdCwgciA9IHIsIHNpZ21hID0gc2lnbWEpCnB1dF9wcm0gPC0gb3B0aW9uX3BybShTID0gUywgWCA9IFgsIHQgPSB0LCByID0gciwgc2lnbWEgPSBzaWdtYSwgcHV0ID0gVFJVRSkKCmNhbGxfcGF5IDwtIHBheV9vZmZfdmFscyhwcmVtaXVtID0gY2FsbF9wcm0sIFMgPSBTLCBYID0gWCkKcHV0X3BheSA8LSBwYXlfb2ZmX3ZhbHMocHJlbWl1bSA9IHB1dF9wcm0sIFMgPSBTLCBYID0gWCwgcHV0ID0gVFJVRSkKcHV0X2NhbGwgPC0gZGF0YS5mcmFtZShzcG90ID0gY2FsbF9wYXkkeCwgY2FsbCA9IGNhbGxfcGF5JHksIHB1dCA9IHB1dF9wYXkkeSkgJT4lIG11dGF0ZShjYWxsX21pbnVzX3B1dCA9IGNhbGwgLSBwdXQpCgpwIDwtIGdncGxvdChwdXRfY2FsbCkgKwogIGdlb21fbGluZShhZXMoeCA9IHNwb3QsIHkgPSBjYWxsKSwgY29sb3IgPSAic3RlZWxibHVlIikgKwogIGdlb21fbGluZShhZXMoeCA9IHNwb3QsIHkgPSAtcHV0KSwgY29sb3IgPSAidG9tYXRvIikgKwogIGdlb21fbGluZShhZXMoeCA9IHNwb3QsIHkgPSBjYWxsX21pbnVzX3B1dCksIGNvbG9yID0gInR1cnF1b2lzZSIpICsKICB4bGFiKCJzcG90IikgKyB5bGFiKCJwYXkgb2ZmIikKZ2dwbG90bHkocCwgd2lkdGggPSA4MDApCgpYIC0gWCAqIGV4cCgtMSAqIHIgKiB0KQpgYGAKCiMgUHV0LWNhbGwgcGFyaXR5CgpgYGB7cn0KUyA8LSA0MgpYIDwtIDQ1CnQgPC0gMzY1LzM2NQpyIDwtIDAuMDUKc2lnbWEgPC0gMC4xCgpDIDwtIG9wdGlvbl9wcm0oUz1TLCBYPVgsIHQ9dCwgcj1yLCBzaWdtYT1zaWdtYSkKUCA8LSBvcHRpb25fcHJtKFM9UywgWD1YLCB0PXQsIHI9ciwgc2lnbWE9c2lnbWEsIHB1dD1UUlVFKQpYX1BWIDwtIFgqZXhwKC1yKnQpCgpjYXQoIkMgPSIsIEMsICIsIFAgPSIsIFAsICIsIFhfUFYgPSIsIFhfUFYsICI9PiBDICsgWF9QViAtIFAgPSIsIEMgKyBYX1BWIC0gUCwgIj0gUyIpCmBgYAoK